/**
 * @autor Quirino Brizi
 */
var editor = View.extend({
	/**
	 * The HTML code that represent the editor.
	 */
	html: '<div class="vcl-editor-table" id="vcl-editor-container"><div class="vcl-editor-row"><div class="vcl-editor-inner"><textarea id="vcl-editor"></textarea></div><div class="vcl-editor-inner"><input type="text" id="vcl-editor-name" value="" /><div id="vcl-editor-menu"><input type="button" class="vcl-editor-menu-button" id="vcl-editor-close" value="close" /><input type="button" class="vcl-editor-menu-button" id="vcl-editor-use" value="use" /><input type="button" class="vcl-editor-menu-button" id="vcl-editor-load" value="load" /><input type="button" class="vcl-editor-menu-button" id="vcl-editor-discard" value="discard" /></div><div id="vcl-editor-logger"></div></div></div></div>',
	_open: false,
	/**
	 * initialise the class
	 * @param o an object that contains initialisation parameters.
	 */
	init: function(o){
		if(this._open) { return; }
		
		if(!F.valid(o)) {
			return;
		}
		if(!F.valid(o.container)) {
			// TODO handle exception
			return;
		}
		/*
		 * Add the HTML code to the container;
		 */
		o.container.append($(this.html));
		this.container = o.container.find('#vcl-editor-container');
		/*
		 * Retrieve all the action elements
		 */
		this.name = this.container.find('#vcl-editor-name');
		this.textarea = this.container.find('#vcl-editor');
		this.logger = this.container.find('#vcl-editor-logger');
		var close = this.container.find('#vcl-editor-close'), use = this.container.find('#vcl-editor-use'), 
			load = this.container.find('#vcl-editor-load'), discard = this.container.find('#vcl-editor-discard');
		var self = this;
		/*
		 * Register the textarea key handler
		 */
		this.textarea.keypress(function(e){self.handler(e,self)});
		/*
		 * Define the actions
		 */
		close.click(function(e){ self.hide(); });
		use.click(function(e){
			var name = self.name.val();
			F.ajax('node/use/'+o.id+"?name="+name,'GET',null,false,true,null,function(resp){
				self.logger.tex(resp[0]);
				},
				function(resp){self.logger.text("Error!! " + resp);}
			);
		});
		load.click(function(e){
			var vcl = self.quote(self.textarea.val());
			var name = self.name.val();
			F.ajax('node/inline/'+o.id+"?name="+name+"&vcl="+vcl,'GET',null,false,true,null,function(resp){
				self.logger.text(resp[0]);
				},
				function(resp){self.logger.text("Error!! " + resp);}
			);
		});
		discard.click(function(e){
			var name = self.name.val();
			F.ajax('node/discard/'+o.id+"?name="+name,'GET',null,false,true,null,function(resp){
					self.logger.text(resp[0]);
				},
				function(resp){self.logger.text("Error!! " + resp);}
			);
		});
	},
	/**
	 * Show the current view, for more flexibility the implementation is left to the implementor.
	 */
	show: function() {
		this.container.css({'display':'table'});
		this._open = true;
	},
	/**
	 * This function is called after the show method, it is useful when a the view is rendering an area 
	 * but the main view (or one of its parent) display properties is set to none getting the size of the 
	 * view equal to zero. 
	 */
	afterShow: function() {},
	/**
	 * Hide the current view, to achieve more flexibility in data presentation logic the implementation 
	 * is left to the implementor. 
	 */
	hide: function() {
		this.container.css({'display':'none'});
		this._open = false;
	},
	/**
	 * Render the current view, this method is supposed to be invoked by the controller, so the data 
	 * are ready to be shown to the end user. 
	 */
	render: function(o) {
		this.name.val(o.name);
		this.textarea.val(this.format(o.code));
	},
	/**
	 * Format the given text adding new line and tabulation
	 * @param text the text to format
	 * @returns the formatted text;
	 */
	format: function(text) {
		var s = text;
		/*
		 * Remove all the spaces that follow { or precedes }
		 */
		s = s.replace(/{\s/g, "{");
		s = s.replace(/\s}/g, "}");
		/*
		 * Replaces all open curly bracket not followed by \r\n or \n with {\n\t
		 */
		s = s.replace(/\{(?![\r?\n])/g,"{\n\t");
		/*
		 * Replaces all close curly bracket not followed by \r\n or \n with \n}\n
		 */
		s = s.replace(/\}(?![\r?\n])/g, "\n}\n");
		/*
		 * Replaces all closed curly bracket not preceded by \n and followed by \r\n or \n with \n}
		 */
		s = s.replace(/[^\n]\}(?=[\r?\n])/g, "\n}");
		/*
		 * Replaces all comma bracket not followed by \r\n or \n with ;\n
		 */
		s = s.replace(/;(?![\r?\n])/g, ";\n\t");
		return s;
	},
	/**
	 * Quote and escape the given text.
	 * @param text the string to quote and escape.
	 * @returns String the quoted string. 
	 */
	quote: function(text) {
		var s = text;
		s = s.replace(/[\r?\n\t]/g, "");
		s = s.replace(/"/g,"\\\"");
		return '"' + s + '"';
	},
	handler: function(e, self) {
		if(e.keyCode == 9) {
			// TAB
			var tab = "\t";
			var pos = self._getCaretPosition();
			var text = self.textarea.val();
			var ntext = text.substring(0,pos) + tab + text.substring(pos);
			self.textarea.val(ntext);
		}
	},
	_getCaretPosition: function() {
		var pos = 0;
		if(this.textarea.selectionStart || this.textarea.selectionStart == '0') {
			//FF
			pos = this.textarea.selectionStart;
		} else if(document.selection) {
			// IE
			this.textarea.focus();
			var sel = document.selection.createRange();
			sel.moveStart ('character', -this.textarea.value.length);
			pos = sel.text.length;
		}
		return pos;
	}
});
window.F.editor = editor;